/******************************************************************************
 * @project Zebra
 * @brief
 * @author yaochuan
 * @module com.ezebra.zebra.utils.file
 * @date 2016/10/19
 * @version 0.1
 * @history v0.1, 2016/10/19, by yaochuan
 * <p>
 * Copyright (C) 2016
 ******************************************************************************/
package com.buildings.util;

import android.content.ContentResolver;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.provider.MediaStore;
import android.text.TextUtils;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileChannel;
import java.util.List;

/**
 * Created by yaochuan on 2016/10/19.
 */
public class FileUtil {
	private static final String TAG = "FileUtil";
	public static final SdcardFileUtil sdcard = new SdcardFileUtil();
	private static InternalFileUtil sInternalInstance;
//	private static Context mContext;

	public static void context(Context context) {
//		mContext = context;
		sInternalInstance = new InternalFileUtil(context);
	}

	public static InternalFileUtil internal() throws Exception {
		if (sInternalInstance == null) {
			throw new Exception();
		}
		return sInternalInstance;
	}

	public static InternalFileUtil internal(Context context) {
		if (sInternalInstance == null) {
			sInternalInstance = new InternalFileUtil(context);
		}
		return sInternalInstance;
	}

	/**
	 * Whether the path specified is Directory
	 *
	 * @param path full path of the file/dir
	 * @return true: the path is dir
	 */
	public static boolean isDirectory(String path) {
		return FileUtilBase.isDirectory(path);
	}

	/**
	 * Get the file name from a full path. The file name is usually after the last '/'
	 *
	 * @param path the full path of the file
	 * @return file name
	 */
	public static String getFileName(String path) {
		return FileUtilBase.getFileName(path);
	}

	/**
	 * Get the deepest directory of the file.
	 *
	 * @param path         the full path of the file
	 * @param endWithSlash whether the result end with a slash("/")
	 * @return the deepest directory of the file, if the path is a directory, return the name of itself
	 */
	public static String getDirectoryPath(String path, boolean endWithSlash) {
		return FileUtilBase.getDirectoryPath(path, endWithSlash);
	}

	public static File createAbsoluteFile(String dir, String fileName) {
		File fileDir = new File(dir);
		fileDir.mkdirs();

		File file = new File(dir, fileName);
		try {
			file.createNewFile();
			return file;
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}

	public static boolean isAbsoluteFileExist(String path) {
		File file = new File(path);
		return file.exists();
	}

	public static boolean isAbsoluteFileExist(String path, String fileName) {
		File file = new File(path, fileName);
		return file.exists();
	}

	public static long getFileSize(String fullPath) {
		File file = new File(fullPath);
		return file.length();
	}

	public static boolean removeAbsoluteFile(String path, String fileName) {
		File file = new File(path, fileName);
		if (file.exists()) {
			file.delete();
			return true;
		}
		return false;
	}
	public static boolean mergeFiles(List<String> fpaths, String resultPath) {
		if (fpaths == null || fpaths.size() < 1 || TextUtils.isEmpty(resultPath)) {
			return false;
		}
		if (fpaths.size() == 1) {
			return new File(fpaths.get(0)).renameTo(new File(resultPath));
		}

		File[] files = new File[fpaths.size()];
		for (int i = 0; i < fpaths.size(); i ++) {
			files[i] = new File(fpaths.get(i));
			if (TextUtils.isEmpty(fpaths.get(i)) || !files[i].exists() || !files[i].isFile()) {
				return false;
			}
		}

		File resultFile = new File(resultPath);

		try {
			FileChannel resultFileChannel = new FileOutputStream(resultFile, true).getChannel();
			for (int i = 0; i < fpaths.size(); i ++) {
				FileChannel blk = new FileInputStream(files[i]).getChannel();
				resultFileChannel.transferFrom(blk, resultFileChannel.size(), blk.size());
				blk.close();
			}
			resultFileChannel.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
			return false;
		} catch (IOException e) {
			e.printStackTrace();
			return false;
		}

		for (int i = 0; i < fpaths.size(); i ++) {
			files[i].delete();
		}

		return true;
	}

	public static File uriToFile(Uri uri, Context context) {
		String path = null;
		if ("file".equals(uri.getScheme())) {
			path = uri.getEncodedPath();
			if (path != null) {
				path = Uri.decode(path);
				ContentResolver cr = context.getContentResolver();
				StringBuffer buff = new StringBuffer();
				buff.append("(").append(MediaStore.Images.ImageColumns.DATA).append("=").append("'" + path + "'").append(")");
				Cursor cur = cr.query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, new String[] { MediaStore.Images.ImageColumns._ID, MediaStore.Images.ImageColumns.DATA }, buff.toString(), null, null);
				int index = 0;
				int dataIdx = 0;
				for (cur.moveToFirst(); !cur.isAfterLast(); cur.moveToNext()) {
					index = cur.getColumnIndex(MediaStore.Images.ImageColumns._ID);
					index = cur.getInt(index);
					dataIdx = cur.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
					path = cur.getString(dataIdx);
				}
				cur.close();
				if (index == 0) {
				} else {
					Uri u = Uri.parse("content://media/external/images/media/" + index);
					System.out.println("temp uri is :" + u);
				}
			}
			if (path != null) {
				return new File(path);
			}
		} else if ("content".equals(uri.getScheme())) {
			// 4.2.2以后
			String[] proj = { MediaStore.Images.Media.DATA };
			Cursor cursor = context.getContentResolver().query(uri, proj, null, null, null);
			if (cursor.moveToFirst()) {
				int columnIndex = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
				path = cursor.getString(columnIndex);
			}
			cursor.close();

			return new File(path);
		} else {
			//Log.i(TAG, "Uri Scheme:" + uri.getScheme());
		}
		return null;
	}
}
